#include <iostream>
#include <string>
#include <memory>
using namespace std;

// ==================== 子系统类 ====================

// DVD 播放器
class DVDPlayer
{
public:
    void on() { cout << "DVD Player ON\n"; }
    void play(const string &movie) { cout << "Playing movie: " << movie << endl; }
    void off() { cout << "DVD Player OFF\n"; }
};

// 投影仪
class Projector
{
public:
    void on() { cout << "Projector ON\n"; }
    void wideScreenMode() { cout << "Projector set to widescreen mode (16:9)\n"; }
    void off() { cout << "Projector OFF\n"; }
};

// 环绕音响
class SurroundSound
{
public:
    void on() { cout << "Surround Sound ON\n"; }
    void setVolume(int level) { cout << "Volume set to " << level << endl; }
    void off() { cout << "Surround Sound OFF\n"; }
};

// 灯光系统
class TheaterLights
{
public:
    void dim(int level) { cout << "Lights dimmed to " << level << "%\n"; }
    void on() { cout << "Lights ON\n"; }
};

// ==================== 外观类 ====================

class HomeTheaterFacade
{
private:
    shared_ptr<DVDPlayer> dvd;
    shared_ptr<Projector> projector;
    shared_ptr<SurroundSound> sound;
    shared_ptr<TheaterLights> lights;

public:
    HomeTheaterFacade(shared_ptr<DVDPlayer> d, shared_ptr<Projector> p,
                      shared_ptr<SurroundSound> s, shared_ptr<TheaterLights> l)
        : dvd(d), projector(p), sound(s), lights(l) {}

    void watchMovie(const string &movie)
    {
        cout << "\n--- Get ready to watch a movie ---\n";
        lights->dim(20);
        projector->on();
        projector->wideScreenMode();
        sound->on();
        sound->setVolume(8);
        dvd->on();
        dvd->play(movie);
        cout << "--- Movie started ---\n\n";
    }

    void endMovie()
    {
        cout << "\n--- Shutting movie theater down ---\n";
        dvd->off();
        sound->off();
        projector->off();
        lights->on();
        cout << "--- Movie ended ---\n\n";
    }
};

// ==================== 客户端调用 ====================

int main()
{
    // 创建子系统对象
    auto dvd = make_shared<DVDPlayer>();
    auto projector = make_shared<Projector>();
    auto sound = make_shared<SurroundSound>();
    auto lights = make_shared<TheaterLights>();

    // 创建外观对象
    HomeTheaterFacade homeTheater(dvd, projector, sound, lights);

    // 客户端只需调用两行代码
    homeTheater.watchMovie("Inception");
    homeTheater.endMovie();

    return 0;
}
